import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Component;
import java.awt.Composite;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Collection;
import java.util.List;

import javax.swing.JComponent;

import org.pushingpixels.trident.Timeline;

import edu.jhu.tcj.purfuit.Board;
import edu.jhu.tcj.purfuit.Game;
import edu.jhu.tcj.purfuit.Player;
import edu.jhu.tcj.purfuit.Space;
import edu.jhu.tcj.purfuit.Turn;
import edu.jhu.tcj.purfuit.Turn.TurnState;

public class GameBoardPanel extends GamePanel implements PropertyChangeListener {

	private final Application application;
	private Game game;
	private int zeroX = 15;
	private int zeroY = 15;
	private int width = 45;
	private int spaceBetween = 15;
	private float value = 1.0f;
	public final Timeline timeline = new Timeline(this);
	SoundManager soundManager;
	public GameBoardPanel(Application application, SoundManager sm) {
		soundManager = sm;
		this.application = application;
		setLayout(null);
		
		timeline.addPropertyToInterpolate("value", 1.0f, 0.0f);
		timeline.setDuration(2000);
		
		
		
	}
	
	public void setValue(float newValue) {
		this.value = newValue;
		repaint();
	}

	public void setGame(Game gameToSet) {
		if (gameToSet == this.game) {
			return;
		}
		removeAll();
		this.game = gameToSet;
		this.game.addPropertyChangeListener(Turn.TURN_STATE_UPDATE, this);

		Board board = game.getBoard();
		Space[][] edges = board.getEdges();

		// North
		for (int i = 0; i < edges[0].length; i++) {
			JComponent spaceButton = new SpaceUI(edges[0][i], game, application);
			spaceButton.setBounds(zeroX + (i * (width + spaceBetween)), zeroY,
					45, 45);
			add(spaceButton);
		}

		// East
		for (int i = 0; i < edges[1].length; i++) {
			JComponent spaceButton = new SpaceUI(edges[1][i], game, application);
			spaceButton.setBounds(zeroX + (8 * (width + spaceBetween)), zeroY
					+ (i * (width + spaceBetween)), 45, 45);
			add(spaceButton);
		}

		// South
		for (int i = 0; i < edges[2].length; i++) {
			JComponent spaceButton = new SpaceUI(edges[2][i], game, application);
			spaceButton.setBounds(zeroX + (8 * (width + spaceBetween))
					- (i * (width + spaceBetween)), zeroY
					+ (8 * (width + spaceBetween)), 45, 45);
			add(spaceButton);
		}

		// West
		for (int i = 0; i < edges[3].length; i++) {
			JComponent spaceButton = new SpaceUI(edges[3][i], game, application);
			spaceButton.setBounds(zeroX, zeroY + (8 * (width + spaceBetween))
					- (i * (width + spaceBetween)), 45, 45);
			add(spaceButton);
		}

		Space[][] spokes = board.getSpokes();

		for (int i = 0; i < spokes[0].length; i++) {
			JComponent spaceButton = new SpaceUI(spokes[0][i], game,
					application);
			spaceButton.setBounds(zeroX + (4 * (width + spaceBetween)), zeroY
					+ (3 * (width + spaceBetween))
					- ((spokes[0].length - 1 - i) * (width + spaceBetween)),
					45, 45);
			add(spaceButton);
		}

		for (int i = 0; i < spokes[1].length; i++) {
			JComponent spaceButton = new SpaceUI(spokes[1][i], game,
					application);
			spaceButton.setBounds(zeroX + (5 * (width + spaceBetween))
					+ ((spokes[1].length - 1 - i) * (width + spaceBetween)),
					zeroY + (4 * (width + spaceBetween)), 45, 45);
			add(spaceButton);
		}

		for (int i = 0; i < spokes[2].length; i++) {
			JComponent spaceButton = new SpaceUI(spokes[2][i], game,
					application);
			spaceButton.setBounds(zeroX + (4 * (width + spaceBetween)), zeroY
					+ (5 * (width + spaceBetween))
					+ ((spokes[2].length - 1 - i) * (width + spaceBetween)),
					45, 45);
			add(spaceButton);
		}

		for (int i = 0; i < spokes[3].length; i++) {
			JComponent spaceButton = new SpaceUI(spokes[3][i], game,
					application);
			spaceButton.setBounds(zeroX + (3 * (width + spaceBetween))
					- ((spokes[3].length - 1 - i) * (width + spaceBetween)),
					zeroY + (4 * (width + spaceBetween)), 45, 45);
			add(spaceButton);
		}

		JComponent centerSpaceButton = new SpaceUI(board.getCenterSpace(),
				game, application);
		centerSpaceButton.setBounds(zeroX + (4 * (width + spaceBetween)), zeroY
				+ (4 * (width + spaceBetween)), 45, 45);
		add(centerSpaceButton);

		DieUI dieUI = new DieUI(game.getDie(), game);
		dieUI.setBounds(650, 410, 40, 40);
		add(dieUI);

		List<Player> players = game.getPlayers();
		int y = 0;
		for (Player player : players) {
			PlayerUI playerUI = new PlayerUI(player, game);
			playerUI.setBounds(630, y, 100, 100);
			y = y + 100;
			add(playerUI);
		}

		y = 0;
		for (Player player : players) {
			ArrowUI arrowUI = new ArrowUI(player, game);
			arrowUI.setBounds(575, y, 50, 50);
			y = y + 100;
			add(arrowUI);
		}
		repaint();

	}

	private String chooseSpaceText = "Choose a space";
	private String rollText = "Click to Roll";
	private String buttonText = rollText;
	
	protected void paintComponent(Graphics graphics) {
		Graphics2D g = (Graphics2D) graphics;


		
		
		
		super.paintComponent(g);
		g.setColor(Color.LIGHT_GRAY);
		g.fillRect(0, 0, 800, 600);
		g.setColor(new Color(79, 129, 189));

		graphics.fillRoundRect(600, 460, 150, 75, 20, 20);
		g.setColor(Color.black);
		g.setFont(new Font("Tahoma", Font.PLAIN, 22));
		if (buttonText.equals(rollText)) {
		g.drawString(buttonText, 620, 510);
		} else {
			g.setFont(new Font("Tahoma", Font.PLAIN, 20));	
			g.drawString(buttonText, 605, 500);	
		}

		// g.fillRect(600,440,150,100);
		
//		Composite oldComp = g.getComposite();
//
//		Composite alphaComp = AlphaComposite.getInstance(
//				AlphaComposite.SRC_OVER, value);
//
//		g.setComposite(alphaComp);
//		g.setColor(Color.white);
//		g.fillRect(0, 0, 1000, 1000);
//		g.setComposite(oldComp);
		
	}

	@Override
	public void mouseClicked(MouseEvent e) {
		int x = e.getPoint().x;
		int y = e.getPoint().y - 50;
		if (x > 600 && x < 750 && y > 440 && y < 540) {
			game.getTurn().startPlayersTurn(game.getPlayersTurn());
		}
		soundManager.diceRoll();
	}

	@Override
	public void propertyChange(PropertyChangeEvent evt) {
		Object newValue = evt.getNewValue();
		if (newValue instanceof TurnState) {
			TurnState turnState = (TurnState) newValue;
			switch (turnState) {
			case WaitingToRoll:
				if (TurnState.WaitingToAnswerQuestion.equals(evt.getOldValue())) {
					application.ShowCorrectPanel(game);
				} else {
					application.showGameBoardPanel(game);
				}
				buttonText = rollText;
				break;
			case WaitingToChooseSpace:
				Collection<Space> availableSpaces = game.getTurn().getAvailableSpaces();
				Component[] components = getComponents();
				for (Component component : components) {
					if (component instanceof SpaceUI) {
						for (Space space : availableSpaces) {
							if (space == ((SpaceUI) component).getSpace()) {
								((SpaceUI) component).setHighlighted(true);
								component.repaint();
							}
						}
					}
				}
				buttonText = chooseSpaceText;
				break;
			case WaitingToAnswerQuestion:
				application.showQuestionPanel(game.getTurn()
						.getCurrentQuestion());
				buttonText = rollText;
				break;
			case TurnOver:
				application.ShowIncorrectPanel(game);
				buttonText = rollText;
				// application.showGameBoardPanel(game);
				break;
			case GameOver:
				application.showEndGamePanel(game);
				break;
			}
		}
		repaint();
	}
}
